<template>
  <div class="app-container production-progress-box">
    <div class="top-box">
      <div class="box-l">
        <span class="pro-title">生产进度：</span>
        <span
          >{{ progressTitle.workType }} {{ progressTitle.dateTime }} 排产</span
        >
        <span class="op-btn" @click="btnRefresh">刷新</span>
      </div>
      <div class="put-away">
        <el-button
          type="primary"
          @click="getProgressDetail"
          style="margin-right: 10px"
          plain
          icon="el-icon-s-management"
          >物料</el-button
        >
        <el-select
          placeholder="选择车间"
          v-model="queryParams.workType"
          @change="changeWorkType"
        >
          <el-option
            v-for="item in optionsworkType"
            :key="item.dictValue"
            :label="item.dictLabel"
            :value="item.dictValue"
          >
          </el-option>
        </el-select>
        <el-select
          placeholder="选择时间"
          v-model="timeSlot"
          @change="changeTime"
        >
          <el-option label="全部" value=""></el-option>
          <el-option label="三天" value="0"></el-option>
          <el-option label="七天" value="1"></el-option>
          <el-option label="一个月" value="2"></el-option>
        </el-select>
        <el-button
          type="info"
          @click="btnScreen"
          plain
          icon="el-icon-camera-solid"
          >截图</el-button
        >
      </div>
    </div>
    <!-- 进度图 -->
    <div class="progress-img" v-loading="loading">
      <div
        id="prsWorkProgress"
        :style="{ width: '100%', height: maxHeight + 'px' }"
      ></div>
    </div>
    <!-- 物料抽屉 -->
    <el-drawer
      :title="
        progressTitle.workType + ' ' + progressTitle.dateTime + ' ' + '排产'
      "
      :visible.sync="drawer"
      :direction="direction"
      size="880px"
      class="de-drawer-detail"
    >
      <div class="drawer-detail-table">
        <div style="text-align: center; margin-bottom: 15px">
          <span></span>
        </div>
        <el-table
          ref="tableDetailHeight"
          :data="drawerTableData"
          border
          style="width: 100%"
          v-loading="drawerTableLoading"
          @row-click="handleViewBill"
          :height="drawerTableMaxHeight"
        >
          <el-table-column type="index" width="50" align="center" label="序号">
          </el-table-column>
          <el-table-column
            label="物料编码"
            align="center"
            prop="invCode"
            width="110"
          >
            <template slot-scope="scope">
              <span>{{ scope.row.invCode }}</span>
            </template>
          </el-table-column>
          <el-table-column label="物料名称" align="center">
            <template slot-scope="scope">
              <span>{{ scope.row.invName }} {{ scope.row.invAttribute }}</span>
            </template>
          </el-table-column>
          <el-table-column
            label="主计量"
            align="center"
            prop="unitName"
            width="60"
          />
          <el-table-column
            label="生产线"
            align="center"
            prop="beltline"
            width="100"
          />

          <el-table-column
            prop="invQuantity"
            label="生产数量"
            align="center"
            width="120"
          >
            <template v-slot="scope">
              <div style="text-align: right">
                <span
                  v-if="
                    scope.row.invQuantity !== undefined &&
                    scope.row.invQuantity !== '' &&
                    scope.row.invQuantity !== null
                  "
                  >{{ scope.row.invQuantity.toFixed(2) }}</span
                >
              </div>
            </template>
          </el-table-column>
          <el-table-column
            prop="invQuantity"
            label="生产时间"
            align="center"
            width="150"
          >
            <template v-slot="scope">
              <div>
                <span
                  v-if="
                    scope.row.arrangeDate !== undefined &&
                    scope.row.arrangeDate !== '' &&
                    scope.row.arrangeDate !== null
                  "
                  >{{ scope.row.arrangeDate | inMaterTime }}</span
                >
              </div>
            </template>
          </el-table-column>
          <el-table-column label="生产进度" align="center" width="80">
            <template v-slot="scope">
              <div style="text-align: right">
                <span
                  v-if="
                    scope.row.invQuantity !== undefined &&
                    scope.row.invQuantity !== '' &&
                    scope.row.invQuantity !== null &&
                    scope.row.wiQuantity !== undefined &&
                    scope.row.wiQuantity !== '' &&
                    scope.row.wiQuantity !== null
                  "
                  >{{
                    (
                      (scope.row.wiQuantity / scope.row.invQuantity).toFixed(
                        2
                      ) * 100
                    ).toFixed(2) + "%"
                  }}</span
                >
                <span v-else> 0.00% </span>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { dictMatching, listProgress, detailProgress } from "../../api/progress";
import * as echarts from "echarts";
//并行请求
import axios from "axios";
export default {
  name: "Progress",
  data() {
    return {
      // 遮罩层
      loading: true,
      //最大高度
      maxHeight: "",
      //标题
      progressTitle: {
        workType: "",
        dateTime: "",
      },
      // 查询进度图表
      queryParams: {
        flag: "",
        workType: "",
      },

      // 查询进度明细参数
      queryParamsDetail: {
        pageNum: 1,
        pageSize: 100,
        code: "",
        name: "",
      },
      //业务类型->车间
      optionsworkType: [],
      //最小时间段
      minDate: null,
      //最大时间段
      maxDate: null,
      //进度图实例化
      prsWorkProgress: null,
      //进度图产线数据
      productionLine: [],
      // 进度图数据
      prsWorkData: [],
      //搜索车间
      workType: "",
      //搜索时间段
      timeSlot: "",
      //截图名称
      downLoadName: "车间进度图",
      //物料抽屉
      drawerTableLoading: false,
      drawerTableMaxHeight: null,
      drawerTitle: "",
      drawer: false,
      direction: "rtl",
      drawerTableData: [],
    };
  },
  created() {
    // 初始化
    this.maxHeight = `${document.documentElement.clientHeight}` - 220;
    this.getWorkType().then(() => {
      this.getProgressList().then(() => {
        this.$nextTick(() => {
          this.drawLine();
        });
      });
    });
  },

  methods: {
    //获取业务类型->车间
    getWorkType() {
      return new Promise((resolve) => {
        dictMatching("prs_order_type").then((res) => {
          if (res.code == 200) {
            if (res.data.length > 0) {
              this.optionsworkType = res.data;
              this.queryParams.workType = this.optionsworkType[0].dictValue;
              this.progressTitle.workType = this.optionsworkType[0].dictLabel;
              this.progressTitle.dateTime = "全部";
            } else {
              this.optionsworkType = [];
              this.queryParams.workType = "";
            }

            resolve();
          }
        });
      });
    },

    //车间
    changeWorkType(value) {
      this.optionsworkType.forEach((item) => {
        if (item.dictValue == value) {
          this.progressTitle.workType = item.dictLabel;
        }
      });
      this.getProgressList().then(() => {
        this.drawLine();
      });
    },

    //选择时间段
    changeTime(value) {
      if (value == "") {
        this.progressTitle.dateTime = "全部";
        this.minDate = null;
        this.maxDate = null;
        this.queryParams.flag = value;
        this.getProgressList().then(() => {
          this.drawLine();
        });
        return;
      }

      //最近3天
      if (value == 0) {
        let date = new Date();
        this.minDate = date.getTime();
        let setDate = date.setDate(date.getDate() + 3);
        this.maxDate = setDate;
        this.queryParams.flag = value;
        this.getProgressList().then(() => {
          this.drawLine();
        });
        this.progressTitle.dateTime = "三天";
        return;
      }

      //最近7天
      if (value == 1) {
        let date = new Date();
        this.minDate = date.getTime();
        let setDate = date.setDate(date.getDate() + 7);

        this.maxDate = setDate;
        this.queryParams.flag = value;
        console.log(this.minDate);
        console.log(this.maxDate);
        this.getProgressList().then(() => {
          this.drawLine();
        });
        this.progressTitle.dateTime = "七天";
        return;
      }

      //最近1个月
      if (value == 2) {
        let date = new Date();
        this.minDate = date.getTime();
        let setMonth = date.setMonth(date.getMonth() + 1);
        this.maxDate = setMonth;
        this.queryParams.flag = value;
        this.getProgressList().then(() => {
          this.drawLine();
        });
        this.progressTitle.dateTime = "一个月";
        return;
      }
    },

    //进度图表数据
    getProgressList() {
      return new Promise((resolve) => {
        this.loading = true;
        listProgress(this.queryParams).then((res) => {
          if (res.code == 200) {
            console.log(res.data);
            // 明细
            this.drawerTableData = res.data.detail;
            //产线
            this.productionLine = res.data.productionLine;
            //图表数据
            let data = JSON.parse(JSON.stringify(res.data.prsWorkData));
            if (data.length > 0) {
              data.forEach((item, index) => {
                item.value[0] = parseInt(item.value[0]);
                if (index % 3 == 0) {
                  item.bgColor = "#1890ff"; //颜色深
                  item.bgColor1 = "#61b2fd"; //颜色浅
                }

                if (index % 3 == 1) {
                  item.bgColor = "#5daf34";
                  item.bgColor1 = "#89df5e";
                }

                if (index % 3 == 2) {
                  item.bgColor = "#cf9236";
                  item.bgColor1 = "#f0b65e";
                }
                item.value.push(
                  item.name,
                  item.attribute,
                  item.invQuantity,
                  item.unitName,
                  item.schedule,
                  item.bgColor,
                  item.bgColor1
                );
              });
            }
            this.prsWorkData = data;
            this.loading = false;
            resolve();
          }
        });
      });
    },

    // 车间进度图表
    drawLine() {
      this.prsWorkProgress = echarts.init(
        document.getElementById("prsWorkProgress")
      );
      this.prsWorkProgress.clear();
      this.prsWorkProgress.setOption(this.makeOption());
    },

    //渲染
    makeOption() {
      return {
        tooltip: {
          //自定义提示信息
          formatter: function (params) {
            //params为当前点击图形元素的数据信息的对象
            //计划开始时间
            let planStartDate = params.value[1];
            //计划结束时间
            let planEndDate = params.value[2];
            //加工时长
            let deDay;
            if (params.value[3]) {
              deDay = params.value[3];
            } else {
              deDay = "";
            }

            return (
              params.data.name +
              " " +
              params.data.attribute +
              "<br/>" +
              "生产数量：" +
              params.data.invQuantity +
              params.data.unitName +
              "<br/>" +
              "计划开始时间：" +
              planStartDate +
              "<br/>" +
              "计划结束时间：" +
              planEndDate +
              "<br/>" +
              "加工时长：" +
              deDay +
              "分钟" +
              "<br/>" +
              "进度：" +
              ((params.data.schedule * 100).toFixed(2) + "%")
            );
          },
        },
        title: {
          left: "center",
        },
        dataZoom: [
          {
            //区域缩放组件的类型为滑块，默认作用在x轴上
            type: "slider",
            //区域缩放组件的过滤模式，weakFilter：在进行区域缩放时，允许图形的一部分在坐标系上(可见)，另一部分在坐标系外(隐藏)
            filterMode: "weakFilter",
            showDataShadow: false,
            top: this.maxHeight - 50,
            height: 10,
            //区域缩放组件边框颜色
            borderColor: "transparent",
            //区域缩放组件边框背景
            backgroundColor: "#e2e2e2",
            //区域缩放组件上的手柄的样式
            handleIcon:
              "M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z", // jshint ignore:line
            //手柄大小
            handleSize: 20,
            //为手柄设置阴影效果
            handleStyle: {
              shadowBlur: 6,
              shadowOffsetX: 1,
              shadowOffsetY: 2,
              shadowColor: "#aaa",
            },
            labelFormatter: "",
          },
          {
            //区域缩放组件的类型为内置在坐标系中，默认作用在x轴的坐标系中
            type: "inside",
            //区域缩放组件的过滤模式，weakFilter：在进行区域缩放时，允许图形的一部分在坐标系上(可见)，另一部分在坐标系外(隐藏)
            filterMode: "weakFilter",
          },
          {
            type: "slider",
            yAxisIndex: 0,
            zoomLock: true,
            width: 10,
            right: 10,
            top: 50,
            bottom: 40,
            start: 60,
            end: 100,
            handleSize: 0,
            showDetail: false,
          },
          {
            type: "inside",
            id: "insideY",
            yAxisIndex: 0,
            start: 60,
            end: 100,
            zoomOnMouseWheel: false,
            moveOnMouseMove: true,
            moveOnMouseWheel: true,
          },
        ],
        //图表底板
        grid: {
          height: this.maxHeight - 110,
          left: 70,
          right: 70,
        },
        xAxis: {
          type: "time",
          position: "top",
          min: this.minDate,
          max: this.maxDate,
          axisLabel: {
            formatter: (value, index) => {
              let date = new Date(value);
              let year = date.getFullYear(),
                month = date.getMonth() + 1,
                day = date.getDate(),
                hours = date.getHours(),
                minutes = date.getMinutes(),
                seconds = date.getSeconds();

              if (
                hours == "0" &&
                minutes == "0" &&
                seconds == "0" &&
                seconds == "0"
              ) {
                return year + "-" + month + "-" + day;
              } else {
                if (hours == "0") {
                  hours = "00";
                }
                if (minutes == "0") {
                  minutes = "00";
                }
                if (seconds == "0") {
                  seconds = "00";
                }
                return (
                  year +
                  "-" +
                  month +
                  "-" +
                  day +
                  " " +
                  hours +
                  ":" +
                  minutes +
                  ":" +
                  seconds
                );
              }
            },
          },
          splitLine: {
            show: true,
          },
        },
        yAxis: {
          data: this.productionLine,
          axisTick: {
            alignWithLabel: true, //保证刻度线和标签对齐，当boundaryGap为true的时候有效，不过boundaryGap默认就是true
          },
        },
        legend: {
          left: "70%",
          top: 10,
        },
        series: [
          {
            type: "custom",
            //使用自定义的图形元素
            renderItem: this.renderItem,
            itemStyle: {
              //透明度
              opacity: 1,
              color: "#AACCF9",
            },
            encode: {
              //将维度1和维度2的数据映射到x轴
              x: [1, 2],
              //将维度0的数据映射到y轴
              y: 0,
            },
            data: this.prsWorkData,
          },
        ],
      };
    },

    //自定义画图
    renderItem(params, api) {
      // params为data中的数据项的信息对象    api中是一些开发者可调用的方法集合，可以对data中的数据项进行操作
      let categoryIndex = api.value(0); //取出data中数据项的第一个维度的值
      let schedule = api.value(8);
      let title =
        api.value(4) + " " + api.value(5) + " " + api.value(6) + api.value(7);
      //计划开始日期(在屏幕上的像素值)
      let planStartDate = api.coord([api.value(1), categoryIndex]); //将数据项中的数值对应的坐标系上的点，转换为屏幕上的像素值
      //坐标系上的点：是数据项映射到坐标系的x轴和y轴后，对应的位置
      //屏幕上的像素值：是坐标系上的点，在屏幕上的位置
      //计划结束日期(在屏幕上的像素值)
      let planEndDate = api.coord([api.value(2), categoryIndex]);
      //由于data.value中维度1和维度2的数据会被映射到x轴，而x轴的type为time，即时间轴，
      //所以api.value(1)和api.value(2)获取到的值是将日期转换后的毫秒值
      //设置图形的高度
      let height = 30; //获得Y轴上数值范围为1的一段所对应的像素长度；这是官方文档的注释，对于api.size()方法，目前我还不是很理解；先做个标记??? 以后再说
      //使用graphic图形元素组件，绘制矩形
      //clipRectByRect方法，在绘制矩形时，如果矩形大小超出了当前坐标系的包围盒，则裁剪这个矩形
      let rectShape1 = echarts.graphic.clipRectByRect(
        {
          //矩形的位置
          x: planStartDate[0],
          y: planStartDate[1],
          //矩形的宽高
          width: planEndDate[0] - planStartDate[0],
          height: height,
        },
        {
          //当前坐标系的包围盒
          x: params.coordSys.x,
          y: params.coordSys.y,
          width: params.coordSys.width,
          height: params.coordSys.height,
        }
      );

      let rectShape2 = echarts.graphic.clipRectByRect(
        {
          //矩形的位置
          x: planStartDate[0],
          y: planStartDate[1],
          //矩形的宽高
          width: (planEndDate[0] - planStartDate[0]) * schedule,
          height: height,
        },
        {
          //当前坐标系的包围盒
          x: params.coordSys.x,
          y: params.coordSys.y,
          width: params.coordSys.width,
          height: params.coordSys.height,
        }
      );
      //设置绘制的矩形的元素定义
      return (
        rectShape1 && {
          type: "group",
          children: [
            {
              //类型为矩形
              type: "rect",
              //具体形状
              shape: rectShape1,
              //样式
              style: api.style({
                fill: api.value(10),
                text: title,
                textFill: "#fff",
              }),
            },
            {
              //类型为矩形
              type: "rect",
              //具体形状
              shape: rectShape2,
              //样式
              style: api.style({
                fill: api.value(9),
              }),
            },
          ],
        }
      );
    },

    // 获取进度明细
    getProgressDetail() {
      this.drawer = true;
      setTimeout(() => {
        this.drawerTableMaxHeight =
          `${document.documentElement.clientHeight}` - 175;
      }, 0);
    },

    //刷新
    btnRefresh() {
      // 初始化
      this.maxHeight = `${document.documentElement.clientHeight}` - 220;
      this.getWorkType().then(() => {
        this.getProgressList().then(() => {
          this.$nextTick(() => {
            this.drawLine();
          });
        });
      });
    },

    //截图
    btnScreen() {
      this.downLoadName = this.progressTitle.workType + "进度图";
      let code = this.prsWorkProgress.getDataURL();
      const link = document.createElement("a");
      link.setAttribute("download", this.downLoadName);
      link.setAttribute("href", code);
      link.click();
    },

    //查看详情
    handleViewBill(row) {
      this.$router.push({
        path: "/prs/production/orderview",
        query: {
          detailCode: row.prsCode,
          open: "seeStatus",
          workType: row.workType,
          fmConfig: row.formConfig,
        },
      });
    },
  },
  filters: {
    //时间格式转换
    inMaterTime(time) {
      let date = new Date(time);
      let year = date.getFullYear(),
        month = date.getMonth() + 1,
        day = date.getDate(),
        hours = date.getHours(),
        minutes = date.getMinutes(),
        seconds = date.getSeconds();

      if (hours == "0") {
        hours = "00";
      }
      if (minutes == "0") {
        minutes = "00";
      }
      if (seconds == "0") {
        seconds = "00";
      }
      return (
        year +
        "-" +
        month +
        "-" +
        day +
        " " +
        hours +
        ":" +
        minutes +
        ":" +
        seconds
      );
    },
  },
};
</script>
<style lang="scss">
.production-progress-box {
  .progress-img {
    box-shadow: rgb(0 0 0 / 10%) 0px 0px 20px;
    padding: 20px;
  }

  .top-box {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    justify-content: space-between;
    .box-l {
      .pro-title {
        color: #1890ff;
      }
      .op-btn {
        color: #1890ff;
        margin-left: 15px;
        cursor: pointer;
        &:hover {
          opacity: 0.8;
        }
      }
    }
    .put-away {
      .el-select {
        width: 120px;
        margin-right: 10px;
      }
    }
  }
  .el-drawer__wrapper {
    width: 900px;
    left: inherit;
  }
  .de-drawer-detail {
    .el-drawer.rtl {
      height: calc(100vh - 85px);
      top: auto;
    }
    .drawer-detail-table {
      padding: 0 15px;
    }
    .el-button--medium {
      padding: 8px 10px;
      span {
        font-size: 13px;
      }
    }
    .el-drawer__header {
      margin-bottom: 0;
    }
  }
}
.v-modal {
  display: none;
}

:focus {
  outline: 0;
}
</style>
